
Imports cmplib01

Public Class ctlCreateGroup

    Public Enum InvalidReason_e
        valid = 0
        nounits = 1
        noname = 2
    End Enum

    Const c_SELECTEDTREEITEM As Integer = 0
    Const c_BATTLEGROUPITEM As Integer = 1
    Const c_UNITITEM As Integer = 2
    Const c_ELEMENTGROUPITEM As Integer = 3
    Const c_ELEMENTITEM As Integer = 4
    Const c_ELEMENTOPTION As Integer = 5

    Public Event DeployOOBAsBG(ByRef OOBUnit As BattlegroupChit)

    Private ptrGame As CampaignerGameData

    Private _BaseBattleGroup As BattlegroupChit
    Private _moveTypeNames() As String
    Private ptrDeploymentzone As DeploymentZone

    Private selectedBattleGroup As BattlegroupChit
    Private selectedUnit As ChitUnitTypeMember
    Private selectedNode As CampaignerItemTreeNode
    Private selectedBattleGroupNode As CampaignerItemTreeNode

    Private prevSelectedNode As CampaignerItemTreeNode

    Private clearAllele As ToolStripItem
    Private editMultipleEle As ToolStripItem

    Private _defaultBGIcon As Image
    Private _forceOOB As Boolean = False
    Private _IndicatorMenu As New ToolStripMenuItem("Indicators")


    Public Property defaultBGIcon() As Bitmap
        Get
            Return _defaultBGIcon
        End Get
        Set(ByVal value As Bitmap)
            _defaultBGIcon = value
        End Set
    End Property

    Public Property forceOOB() As Boolean
        Get
            Return _forceOOB
        End Get
        Set(ByVal value As Boolean)
            _forceOOB = value
            btnAddUnit.Enabled = False
        End Set
    End Property

    Public Property Game() As CampaignerGameData
        Get
            Return ptrGame
        End Get
        Set(ByVal value As CampaignerGameData)
            ptrGame = value
            If Not ptrGame Is Nothing Then lblBGPC.Text = ptrGame.BattlegroupMaxPointValue
            If Not ptrGame Is Nothing Then BuildPopup()
        End Set
    End Property

    Public Property moveTypeNames() As String()
        Get
            Return _moveTypeNames
        End Get
        Set(ByVal value As String())
            _moveTypeNames = value
        End Set
    End Property

    Public Property BaseBattleGroup() As BattlegroupChit
        Get
            Return _BaseBattleGroup
        End Get
        Set(ByVal value As BattlegroupChit)
            _BaseBattleGroup = value
            If Not _BaseBattleGroup Is Nothing Then Populate()
        End Set
    End Property

    Public Property DeploymentZone() As DeploymentZone
        Get
            Return ptrDeploymentzone
        End Get
        Set(ByVal value As DeploymentZone)
            ptrDeploymentzone = value
        End Set
    End Property

    Private Sub Populate()
        Try
            '// this is just our initial populate
            tvwBattlegroupView.Nodes.Clear()
            tvwBattlegroupView.Nodes.Add(PopulateBattlegroup(_BaseBattleGroup))
            tvwBattlegroupView.SelectedNode = tvwBattlegroupView.Nodes(0)

            tvwBattlegroupView.ShowNodeToolTips = True

            '// update the options for OOB selection, etc.
            If ptrGame.ForceOOB = True Then
                btnAddUnit.Enabled = False
                btnRemoveUnit.Enabled = False
            End If

        Catch ex As Exception
            HandleException("ctlCreateGroup.Populate", ex)
        End Try
    End Sub

    Private Function PopulateBattlegroup(ByRef bg As BattlegroupChit) As CampaignerItemTreeNode
        Try
            '// this can be used to add a new bg to an existing one.
            Dim bgNode As New CampaignerItemTreeNode
            bgNode.SelectedImageIndex = c_SELECTEDTREEITEM
            bgNode.ImageIndex = c_BATTLEGROUPITEM

            '// returns a node representing THIS battlegroup and all his little cronies
            bgNode.Text = bg.Name
            bgNode.ItemType = CampaignerItem_cgd.Battlegroup
            bgNode.Item = bg

            For Each coward As ChitMember In bg.members
                If coward.UnitType = GroundChitClass_cgd.Battlegroup Then
                    bgNode.Nodes.Add(PopulateBattlegroup(coward))
                Else
                    PopulateUnits(bgNode, coward)
                End If
            Next

            Return bgNode
        Catch ex As Exception
            Dim errNode As New CampaignerItemTreeNode
            errNode.Text = "Error - item not populated properly"
            Return errNode
        End Try
    End Function

    Private Sub PopulateUnits(ByRef bgNode As CampaignerItemTreeNode, ByRef un As ChitUnitTypeMember)
        Try
            '// uses the passed in node to put in the units. Fun.
            Dim unNode As New CampaignerItemTreeNode

            unNode.SelectedImageIndex = c_SELECTEDTREEITEM
            unNode.ImageIndex = c_UNITITEM

            unNode.ItemType = CampaignerItem_cgd.Unit
            unNode.Item = un
            unNode.Text = un.Name

            bgNode.Nodes.Add(unNode)

        Catch ex As Exception
            Dim errNode As New CampaignerItemTreeNode
            errNode.Text = "Error - item not populated properly"

        End Try
    End Sub

    Private Sub ListElements(ByRef unit As UnitType, ByRef node As CampaignerItemTreeNode)
        Try
            '// uses the passed in units to list the elements. Not fun.
            Dim group As ElementGroup
            Dim EleGroup As GroupableElements = unit.ChitElements

            If unit.ChitElements.Count = 0 Then Exit Sub

            For Each group In EleGroup.Groups
                Dim GroupNode As New CampaignerItemTreeNode
                GroupNode.Text = group.GroupName
                GroupNode.ItemType = CampaignerItem_cgd.ElementGroup
                GroupNode.Item = group
                GroupNode.ImageIndex = c_ELEMENTITEM
                GroupNode.SelectedImageIndex = c_SELECTEDTREEITEM
                node.Nodes.Add(GroupNode)
            Next

            Dim ele As GroupableElement
            Dim optionText As String
            Dim opt As ElementOption

            '// first post the Non-grouped elements
            For Each ele In EleGroup
                If ele.GroupName = "<Ungrouped>" Then
                    Dim ungroupedelenode As New CampaignerItemTreeNode

                    optionText = " "
                    For Each opt In ele.Options
                        Dim optNode As New TreeNode
                        optNode.Text = opt.ElementOptionTypeName & " (" & opt.ElementOptionPointCost & ")"
                        optNode.SelectedImageIndex = c_SELECTEDTREEITEM
                        optNode.ImageIndex = c_ELEMENTOPTION
                        ungroupedelenode.Nodes.Add(optNode)
                    Next

                    ungroupedelenode.Text = ele.Count & "x " & ele.ElementTypeName & " (" & ele.TotalCost & ")"
                    ungroupedelenode.ImageIndex = c_ELEMENTITEM
                    ungroupedelenode.SelectedImageIndex = c_SELECTEDTREEITEM
                    ungroupedelenode.ItemType = CampaignerItem_cgd.Element
                    ungroupedelenode.Item = ele
                    node.Nodes.Add(ungroupedelenode)

                End If
            Next

            '// now go through all of the elements and find the group it belongs to
            For Each ele In EleGroup
                Dim nodie As TreeNode
                For Each nodie In node.Nodes
                    If ele.GroupName = nodie.Text Then
                        Dim eleNode As New CampaignerItemTreeNode

                        optionText = " "
                        For Each opt In ele.Options
                            Dim optNode As New TreeNode
                            optNode.Text = opt.ElementOptionTypeName & " (" & opt.ElementOptionPointCost & ")"
                            optNode.SelectedImageIndex = c_SELECTEDTREEITEM
                            optNode.ImageIndex = c_ELEMENTOPTION
                            eleNode.Nodes.Add(optNode)
                        Next

                        eleNode.Text = ele.Count & "x " & ele.ElementTypeName & " (" & ele.TotalCost & ")"
                        eleNode.ImageIndex = c_ELEMENTOPTION
                        eleNode.SelectedImageIndex = c_SELECTEDTREEITEM
                        eleNode.ItemType = CampaignerItem_cgd.Element
                        eleNode.Item = ele
                        nodie.Nodes.Add(eleNode)
                    End If
                Next
            Next
        Catch ex As Exception
            HandleException("ctlCreateGroup.ListElements", ex)
        End Try
    End Sub

    Private Sub btnAddBattleGroup_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddBattleGroup.Click
        Try
            AddBG()
        Catch ex As Exception
            HandleException("btnAddBattleGroup.Click", ex)
        End Try
    End Sub

    Private Sub btnAddUnit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddUnit.Click
        AddUnit()
    End Sub

    Private Sub btnRemoveBattlegroup_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRemoveBattlegroup.Click
        If tvwBattlegroupView.SelectedNode Is Nothing Then Exit Sub
        If DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).ItemType = CampaignerItem_cgd.Unit Then Exit Sub

        '// if it was an OOB unit, we need to put it back into the list.
        'If selectedBattleGroup.OOBUnit = True Then ptrGame.selectedFaction.OrderOfBattle.Add(selectedBattleGroup)

        RemoveBG(selectedBattleGroup)

    End Sub

    Private Sub btnAddOOBUnit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnAddOOBUnit.Click
        AddOOB()
    End Sub

    Private Sub btnRemoveUnit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnRemoveUnit.Click
        If tvwBattlegroupView.SelectedNode Is Nothing Then Exit Sub
        If selectedUnit Is Nothing Then Exit Sub

        selectedBattleGroup.members.remove(selectedUnit)
        tvwBattlegroupView.Nodes.Remove(tvwBattlegroupView.SelectedNode)
        '// now we need to recalculate the BG
        CalculateProperties(selectedBattleGroup)
        '// and the base bg
        CalculateProperties(_BaseBattleGroup)

        ListProperties()

    End Sub

    Private Sub AddBG()
        Try
            If _BaseBattleGroup Is Nothing Then Exit Sub

            If OKToAddTo(_BaseBattleGroup) = False Then Exit Sub

            Dim newb As New BattlegroupChit
            newb.members = New ChitMembers
            _BaseBattleGroup.members.add(newb)
            newb.Name = "New Battlegroup"
            newb.icon = _defaultBGIcon

            Dim bgNode As New CampaignerItemTreeNode
            bgNode.ItemType = CampaignerItem_cgd.Battlegroup
            bgNode.Item = newb
            bgNode.SelectedImageIndex = c_SELECTEDTREEITEM
            bgNode.ImageIndex = c_BATTLEGROUPITEM
            bgNode.Text = newb.Name
            '// add the node the base battlegroup. 
            tvwBattlegroupView.Nodes(0).Nodes.Add(bgNode)

            '// we need to do a totalling of all totals, but, we flow UP. Lateral groups have no effect on the 
            '// base battlegroup speed.
            CalculateProperties(selectedBattleGroup)
            ListProperties()

        Catch ex As Exception
            HandleException("ctlCreateGroup.AddBG", ex)
        End Try
    End Sub

    Private Sub AddOOB()
        Try
            If _BaseBattleGroup Is Nothing Then Exit Sub '// not sure HOW this could happen.
            If OKToAddTo(_BaseBattleGroup) = False Then Exit Sub

            Dim baseGroupEmpty As Boolean = True

            '// determine if the basebattlegroup has any members. if it does, the player may only ADD to it.
            If _BaseBattleGroup.members.Count > 0 Then
                baseGroupEmpty = False
            End If

            Dim f As New frmSelectOOB
            f.ShowDialog(ptrGame, Me._moveTypeNames, ptrDeploymentzone, baseGroupEmpty)

            If f.ActionCancelled Then Exit Sub

            _BaseBattleGroup.calculateProperties()
            _BaseBattleGroup.deployedpointvalue = _BaseBattleGroup.SuggestedPointValue
            _BaseBattleGroup.CurrentPV = _BaseBattleGroup.SuggestedPointValue

            _BaseBattleGroup.OOBGroup = True
            _BaseBattleGroup.OOBUnit = True

            '// make sure the new group has its PV set as well
            f.SelectedBG.calculateProperties()
            f.SelectedBG.deployedpointvalue = f.SelectedBG.SuggestedPointValue
            f.SelectedBG.CurrentPV = f.SelectedBG.SuggestedPointValue

            '// Max point value check.
            If ptrGame.BattlegroupMaxPointValue > 0 Then
                If _BaseBattleGroup.deployedpointvalue + f.SelectedBG.deployedpointvalue > ptrGame.BattlegroupMaxPointValue Then
                    MessageBox.Show("Adding this unit will push the battlegroup over the maximum allowed point value.", "Max Value", MessageBoxButtons.OK)
                    Exit Sub
                End If
            End If


            '// if they hit the DEPLOY option way out there... let the world know.
            If f.DeployAsBaseGroup = True Then
                RaiseEvent DeployOOBAsBG(f.SelectedBG)
                Exit Sub
            End If

            _BaseBattleGroup.members.add(f.SelectedBG)
            f.SelectedBG.OOBGroup = True

            Dim bgNode As New CampaignerItemTreeNode
            bgNode.ItemType = CampaignerItem_cgd.Battlegroup
            bgNode.Item = f.SelectedBG
            bgNode.SelectedImageIndex = c_SELECTEDTREEITEM
            bgNode.ImageIndex = c_BATTLEGROUPITEM
            bgNode.Text = f.SelectedBG.Name
            '// add the node the base battlegroup. 
            tvwBattlegroupView.Nodes(0).Nodes.Add(bgNode)
            '// make sure that this group's units and elements are shown properly
            For Each un As ChitUnitTypeMember In f.SelectedBG.members
                PopulateUnits(bgNode, un)
            Next

            '// remove the item from the OOB list, but mark it as an OOB unit so we can put it back into the order of battle if they cancel
            f.SelectedBG.OOBUnit = True
            ptrGame.selectedFaction.OrderOfBattle.Remove(f.SelectedBG)

            '// we need to do a totalling of all totals, but, we flow UP. Lateral groups have no effect on the 
            '// base battlegroup speed.
            CalculateProperties(selectedBattleGroup)
            ListProperties()
            SetCurrentPV()

        Catch ex As Exception
            HandleException("ctlCreateGroup.AddOOB", ex)
        End Try
    End Sub

    Private Function OKToAddTo(ByRef bg As BattlegroupChit) As Boolean
        If selectedBattleGroup Is Nothing Then selectedBattleGroup = BaseBattleGroup

        If selectedBattleGroup.UnitType = GroundChitClass_cgd.Unit Then
            MessageBox.Show("You can't add units to other units. You must select a battlegroup to add units to.", "Invalid Item", MessageBoxButtons.OK)
            Return False '// you can't add to a unit!
        End If


        Try
            If selectedBattleGroup.icon.Equals(Nothing) Then
                MessageBox.Show("You must select an icon for this battlgroup before continuing.", "Select Icon", MessageBoxButtons.OK)
                Return False
            End If
        Catch ex As Exception
            MessageBox.Show("You must select an icon for this battlgroup before continuing.", "Select Icon", MessageBoxButtons.OK)
            Return False
        End Try

        Return True

    End Function

    Public Function IsValid() As Boolean
        Try
            Dim reason As InvalidReason_e = InvalidReason_e.nounits

            '// two validity tests. 
            '// 1: At least one unit.
            For Each mem As ChitMember In BaseBattleGroup.members
                If mem.UnitType = GroundChitClass_cgd.Battlegroup Then
                    For Each submem As ChitMember In DirectCast(mem, BattlegroupChit).members
                        If submem.UnitType = GroundChitClass_cgd.Unit Then
                            reason = InvalidReason_e.valid
                            Exit For
                        End If
                    Next
                ElseIf mem.UnitType = GroundChitClass_cgd.Unit Then
                    reason = InvalidReason_e.valid
                    Exit For
                End If
            Next

            '// 2: valid naming
            If BaseBattleGroup.Name = "" Then reason = InvalidReason_e.noname
            For Each mem As ChitMember In BaseBattleGroup.members
                If mem.UnitType = GroundChitClass_cgd.Battlegroup Then
                    If mem.Name = "" Then reason = InvalidReason_e.noname
                End If
            Next


            Select Case reason
                Case InvalidReason_e.valid
                    Return True
                Case InvalidReason_e.nounits
                    '// here we'll make the statement of why its not valid.
                    MessageBox.Show("Battlegroups must have at least one unit.", "Invalid Battlegroup", MessageBoxButtons.OK)
                    Return False
                Case InvalidReason_e.noname
                    MessageBox.Show("All Battlegroups must have a name.", "Invalid Battlegroup", MessageBoxButtons.OK)
                    Return False
            End Select

        Catch ex As Exception
            Return False
        End Try
    End Function

    Private Sub AddUnit()
        '// more than one unit can be added at a time. So, the player might select 5 different units. He can also set a number of
        '// units to add. The form that pops up will have a collection of new units for deployment. These can include elements.
        Try

            '// before the user can add new units, the battlegroup icons must be chosen. Ha!
            If selectedBattleGroup Is Nothing Then Exit Sub

            If OKToAddTo(selectedBattleGroup) = False Then Exit Sub

            Dim f As New frmUnitSelection
            f.ShowDialog(ptrGame)

            '// we need to determine the total point cost for the units. If its too much, reject the addition of the unit/BG
            If ptrGame.BattlegroupMaxPointValue > 0 Then
                If _BaseBattleGroup.CurrentPV + f.TotalPV > ptrGame.BattlegroupMaxPointValue Then
                    MessageBox.Show("Adding this unit will put the total value for the battlegroup above the maximum.", "Battlegroup Point Cap", MessageBoxButtons.OK)
                    Exit Sub
                End If
            End If

            '// we take all the new units from the list and add them to the selected battlegroup. Yah!
            Dim un As UnitType
            For Each un In f.AllUnits
                '// we need to create a new unit member thingie
                Dim mem As New ChitUnitTypeMember
                mem.ptrUnitType = un
                mem.Name = un.Name
                mem.OwningFaction = ptrGame.selectedFaction
                mem.OwningPlayer = ptrGame.selectedPlayer

                selectedBattleGroup.members.add(mem)
                Dim nNode As New CampaignerItemTreeNode
                nNode.ItemType = CampaignerItem_cgd.Unit
                nNode.Item = mem
                nNode.Text = mem.ptrUnitType.TypeName
                selectedNode.Nodes.Add(nNode)
                nNode.SelectedImageIndex = c_SELECTEDTREEITEM
                nNode.ImageIndex = c_UNITITEM

                '// make sure the new unit's rules are all set up too
                For Each rut As RuleType In un.GCRules
                    Dim ru As New Rule
                    ru.ptrRule = rut
                    ru.usesRemaining = 1
                    mem.chitRules.add(ru)
                Next

                '// add attributes
                mem.Attributes = New Collection
                For Each s As String In un.ChitAttributes
                    mem.Attributes.Add(s, s)
                Next

                mem.Indicators = New Collection
                '// indicators are the FUN. And not currently working. Dumbassss! Hey, be nice to me.

                nNode.ToolTipText = ""
                For Each inKey As String In un.Indicators.Keys
                    Dim iin As IIindciator = un.Indicators.Item(inKey)
                    Dim iine As IIndicatorEntry = iin.CreateEntry
                    mem.Indicators.Add(iine)
                    nNode.ToolTipText &= iine.displayText & ControlChars.CrLf
                Next

            Next

            f.Dispose()

            '// we need to do a totalling of all totals, but, we flow UP. Lateral groups have no effect on the 
            '// base battlegroup speed.
            CalculateProperties(selectedBattleGroup)
            ListProperties()

            '// we'll have to caluculate the base battlegroup once again
            CalculateProperties(_BaseBattleGroup)
            SetCurrentPV()
            ListProperties()


        Catch ex As Exception
            HandleException("ctlCreateGroup.AddUnit", ex)
        End Try

    End Sub

    Private Sub SetCurrentPV()
        Try
            '// automatically determines the PV when adding new units and such. Actually gets it from the suggested pv.
            If selectedBattleGroup.overridePointValue = 0 Then
                selectedBattleGroup.CurrentPV = selectedBattleGroup.SuggestedPointValue
            Else
                selectedBattleGroup.CurrentPV = selectedBattleGroup.overridePointValue
            End If


            If BaseBattleGroup.overridePointValue = 0 Then
                BaseBattleGroup.CurrentPV = BaseBattleGroup.SuggestedPointValue
            Else
                BaseBattleGroup.CurrentPV = BaseBattleGroup.overridePointValue
            End If

            lblBaseBGPV.Text = BaseBattleGroup.CurrentPV
            lblBGPointValue.Text = selectedBattleGroup.CurrentPV

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub CalculateProperties(ByRef ptrUnit As BattlegroupChit)
        '// calculates the properties for the battlegroup depending on the units that it is comprised of.
        '// if all the units have the same movement class, thats the one used. Otherwise we use mixed.
        ptrUnit.calculateProperties()
    End Sub

    Private Sub ListProperties()
        '// we list the properties of the selectedbattlegroup and the basebattlegroup
        Try
            ''// yay!
            ''// show the properties for the selected battle group
            txtBattlegroupName.Text = selectedBattleGroup.Name
            picOwner.Image = selectedBattleGroup.icon
            'picEnemy.Image = selectedBattleGroup.Icon(IconImageIndex_cgd.Enemy)
            'picFriendly.Image = selectedBattleGroup.Icon(IconImageIndex_cgd.SameFaction)

            lblBGPointValue.Text = selectedBattleGroup.CurrentPV
            lblMovementSpeed.Text = selectedBattleGroup.MovementSpeed
            lblMovementType.Text = _moveTypeNames(selectedBattleGroup.movementClassID)

            '// base battlegroup
            lblEffective.Text = "'" & _BaseBattleGroup.Name & "' Values"
            lblBaseBGPV.Text = BaseBattleGroup.CurrentPV
            lblBaseBGSpeed.Text = BaseBattleGroup.MovementSpeed
            lblBaseBGMoveType.Text = _moveTypeNames(BaseBattleGroup.MovementClassID)

            '// and the point values remaining
            lblDepZoneRemaining.Text = DeploymentZone.MaxTotalDeploy
            lblFactionRemaining.Text = Game.selectedFaction.FactionFreePoints

            '// size
            lblSizeValue.Text = Game.TextForSize(BaseBattleGroup.Size)

        Catch ex As Exception
            HandleException("ctlCreateGroup.ListProperties", ex)
        End Try
    End Sub

    Private Sub RemoveBG(ByRef BG As BattlegroupChit)
        Try

            If BG Is _BaseBattleGroup Then
                MessageBox.Show("You can not delete the base Battlegroup.", "Can't Delete", MessageBoxButtons.OK, MessageBoxIcon.Hand)
                Exit Sub
            End If

            If BG.OOBGroup = True Then Game.selectedFaction.OrderOfBattle.add(BG)

            _BaseBattleGroup.members.remove(BG)
            tvwBattlegroupView.Nodes.Remove(tvwBattlegroupView.SelectedNode)
            SetCurrentPV()

        Catch ex As Exception
            HandleException("ctlCreateGroup.RemoveBG", ex)
        End Try
    End Sub

    Private Sub RemoveUnit(ByRef Uni As CampaignerItemTreeNode)
        If selectedUnit Is Nothing Then Exit Sub
        If selectedBattleGroup Is Nothing Then Exit Sub

        selectedBattleGroup.members.remove(Uni.Item)
        tvwBattlegroupView.Nodes.Remove(Uni)
        selectedUnit = Nothing
        SetCurrentPV()

    End Sub

    Private Sub tvwBattlegroupView_AfterSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewEventArgs) Handles tvwBattlegroupView.AfterSelect
        Try
            selectedNode = tvwBattlegroupView.SelectedNode

            If tvwBattlegroupView.SelectedNode Is Nothing Then
                selectedUnit = Nothing
                selectedBattleGroup = Nothing
                btnRemoveUnit.Enabled = False
                Exit Sub
            End If

            If DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).ItemType = CampaignerItem_cgd.Battlegroup Then
                selectedBattleGroup = DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).Item
                selectedBattleGroupNode = tvwBattlegroupView.SelectedNode
                If _forceOOB = False Then
                    btnAddUnit.Enabled = True
                End If
            ElseIf DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).ItemType = CampaignerItem_cgd.Unit Then
                selectedBattleGroup = DirectCast(tvwBattlegroupView.SelectedNode.Parent, CampaignerItemTreeNode).Item
                selectedUnit = DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).Item
                selectedBattleGroupNode = tvwBattlegroupView.SelectedNode.Parent
                '// hide the add unit
                btnAddUnit.Enabled = False
                btnRemoveUnit.Enabled = True

                'removeEle.Enabled = True
                clearAllele.Enabled = True
            ElseIf DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).ItemType = CampaignerItem_cgd.Element Then
                selectedBattleGroup = DirectCast(tvwBattlegroupView.SelectedNode.Parent.Parent, CampaignerItemTreeNode).Item
                selectedUnit = DirectCast(tvwBattlegroupView.SelectedNode.Parent, CampaignerItemTreeNode).Item
                selectedBattleGroupNode = tvwBattlegroupView.SelectedNode.Parent.Parent
                btnAddUnit.Enabled = False
                btnRemoveUnit.Enabled = False

                'removeEle.Enabled = True
                clearAllele.Enabled = False
            End If

            ListProperties()

            tvwBattlegroupView.SelectedNode.BackColor = Color.Yellow

        Catch ex As Exception
            HandleException("ctlCreateGroup.tvwBattlegroupView.AfterSelect", ex)
        End Try
    End Sub

    Private Sub txtBattlegroupName_TextChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtBattlegroupName.TextChanged
        If selectedBattleGroup Is Nothing Then Exit Sub
        selectedBattleGroup.Name = txtBattlegroupName.Text
        selectedBattleGroupNode.Text = txtBattlegroupName.Text
        If selectedBattleGroup Is _BaseBattleGroup Then
            lblEffective.Text = "'" & txtBattlegroupName.Text & "' Values"
        End If

    End Sub

    Private Sub picOwner_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles picOwner.Click
        If selectedBattleGroup Is Nothing Then Exit Sub
        SetNewIcon(sender)
        'selectedBattleGroup.OwnerSet = True

    End Sub

    Private Sub SetNewIcon(ByRef pic As PictureBox)
        '// sets the icon into the picture
        Try
            Dim fOpen As New OpenFileDialog
            fOpen.Filter = "Picture Files | *.bmp; *.jpg; *.png"
            fOpen.ShowDialog()

            pic.Image = Image.FromFile(fOpen.FileName)

            ' now we'll update all the images
            If Not selectedBattleGroup Is Nothing Then
                selectedBattleGroup.icon = picOwner.Image
                'selectedBattleGroup.Icon(IconImageIndex_cgd.Enemy) = picEnemy.Image
                'selectedBattleGroup.Icon(IconImageIndex_cgd.SameFaction) = picFriendly.Image
            End If

        Catch ex As Exception

        End Try

    End Sub

    Private Sub tvwBattlegroupView_BeforeSelect(ByVal sender As Object, ByVal e As System.Windows.Forms.TreeViewCancelEventArgs) Handles tvwBattlegroupView.BeforeSelect
        If tvwBattlegroupView.SelectedNode Is Nothing Then Exit Sub

        tvwBattlegroupView.SelectedNode.BackColor = Color.White

    End Sub

    '///// Elements

    Private Sub BuildPopup()

        For Each elemc As ElementClass In ptrGame.ElementMan.DefinedElementClasses

            Dim classitem As New ToolStripMenuItem(elemc.ElementClassName)

            '// add all of the items in this menu type
            For Each eleT As ElementType In ptrGame.ElementMan.DefinedElementTypes
                If eleT.ElementClassName = elemc.ElementClassName Then

                    Dim menitem As New ToolStripMenuItem(eleT.ElementTypeName & " [" & eleT.ElementPointValue & "]")
                    menitem.Tag = eleT
                    classitem.DropDownItems.Add(menitem)
                    '// bind the event handler
                    AddHandler menitem.Click, AddressOf ClickElementMenu

                End If
            Next
            ctxMenu.Items.Add(classitem)

        Next

        ctxMenu.Items.Add("-")
        editMultipleEle = ctxMenu.Items.Add("Element Manager", Nothing, AddressOf ClickEditMultipleEle)
        clearAllele = ctxMenu.Items.Add("Remove all elements", Nothing, AddressOf ClickElementClear)

    End Sub

    Private Sub ClickEditMultipleEle(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            If selectedUnit Is Nothing Then Exit Sub
            Dim unitNode As CampaignerItemTreeNode = Nothing
            Dim unitMember As ChitUnitTypeMember = Nothing

            Select Case DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).ItemType
                Case CampaignerItem_cgd.Battlegroup : Exit Sub

                Case CampaignerItem_cgd.Unit
                    Dim f As New cmplib01.frmElementPicker(ptrGame, selectedUnit)
                    f.ShowDialog()
                    unitNode = tvwBattlegroupView.SelectedNode
                    unitMember = selectedUnit

                Case CampaignerItem_cgd.Element
                    Dim parent As ChitUnitTypeMember = DirectCast(tvwBattlegroupView.SelectedNode.Parent, CampaignerItemTreeNode).Item
                    Dim f As New frmElementPicker(ptrGame, parent)
                    f.ShowDialog()
                    unitNode = tvwBattlegroupView.SelectedNode.Parent
                    unitMember = parent
            End Select

            If Not unitNode Is Nothing Then
                '// clear all elements
                unitNode.Nodes.Clear()

                '// relist all elements
                For Each ele As GroupableElement In unitMember.elements
                    Dim elenode As New CampaignerItemTreeNode
                    If ele.Count = 1 Then
                        elenode.Text = ele.ElementTypeName
                    Else
                        elenode.Text = ele.Count & "x " & ele.ElementTypeName
                    End If
                    elenode.SelectedImageIndex = 0
                    elenode.ImageIndex = 4
                    elenode.ItemType = CampaignerItem_cgd.Element
                    unitNode.Nodes.Add(elenode)
                Next
            End If

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub ClickElementMenu(ByVal sender As Object, ByVal e As System.EventArgs)
        '// here, we add the element to the elements! Yah!
        '// creates a SINGLE groupable element
        Try

            '// 1st, we must have a UNIT selected in the tree.
            If selectedUnit Is Nothing Then Exit Sub

            Select Case DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).ItemType
                Case CampaignerItem_cgd.Battlegroup : Exit Sub
                Case CampaignerItem_cgd.Unit
                    clearAllele.Enabled = True
                    'removeEle.Enabled = False
                Case CampaignerItem_cgd.Element
                    'removeEle.Enabled = True
                    clearAllele.Enabled = False
            End Select

            If selectedUnit.UnitType = GroundChitClass_cgd.Battlegroup Then Exit Sub '// can't add elements to groups. That stupido

            '// create the nodely.
            Dim elenode As New CampaignerItemTreeNode
            Dim ET As ElementType = DirectCast(sender, ToolStripMenuItem).Tag
            elenode.ItemType = CampaignerItem_cgd.Element
            elenode.Text = ET.ElementTypeName 'ET.ElementTypeName & " [" & ET.ElementPointValue & "]"
            elenode.ImageIndex = 4
            elenode.SelectedImageIndex = 0

            Dim gele As New GroupableElement(ET)
            elenode.Item = gele

            '// add the element type to the unit
            selectedUnit.elements.Add(gele)

            tvwBattlegroupView.SelectedNode.Nodes.Add(elenode)
            CalculateProperties(selectedBattleGroup)
            'CalculateProperties(BaseBattleGroup)

            SetCurrentPV()
            ListProperties()

        Catch ex As Exception
            HandleException("frmOOBG.ClickElementMenu", ex)
        End Try
    End Sub

    Private Sub ClickElementClear(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            selectedUnit.elements.Clear()
            CalculateProperties(selectedBattleGroup)
            tvwBattlegroupView.SelectedNode.Nodes.Clear()

            SetCurrentPV()
            ListProperties()

        Catch ex As Exception
            HandleException("frmOOBG.ClickClearElements", ex)
        End Try
    End Sub

    Private Sub ClickRemoveElement(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            Dim cid As CampaignerItemTreeNode = DirectCast(tvwBattlegroupView.SelectedNode.Parent, CampaignerItemTreeNode)
            DirectCast(cid.Item, ChitUnitTypeMember).elements.Remove(DirectCast(tvwBattlegroupView.SelectedNode, CampaignerItemTreeNode).Item)

            tvwBattlegroupView.Nodes.Remove(tvwBattlegroupView.SelectedNode)
            SetCurrentPV()
            ListProperties()

        Catch ex As Exception
            HandleException("frmOOBG.ClickRemoveElement", ex)
        End Try
    End Sub


    Private Sub tvwBattlegroupView_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles tvwBattlegroupView.MouseClick
        If e.Button = Windows.Forms.MouseButtons.Right Then
            ctxMenu.Items.Add(_IndicatorMenu)
            AddIndicatorMenuOptions()
            ctxMenu.Show(tvwBattlegroupView, e.X, e.Y)
        End If
    End Sub






    Private Sub AddIndicatorMenuOptions()
        Try
            Dim cnode As CampaignerItemTreeNode = tvwBattlegroupView.SelectedNode

            Select Case cnode.ItemType
                Case CampaignerItem_cgd.Token
                    Dim cutm As ChitTokenTypeMember = cnode.Item
                    _IndicatorMenu.DropDownItems.Clear()

                    Try
                        If Not cutm.Indicators Is Nothing Then
                            If cutm.Indicators.Count > 0 Then


                                For Each indie As IIndicatorEntry In cutm.Indicators
                                    'Dim indi As IIindciator = cutm.ptrUnitType.Indicators.Item(kay)
                                    'Dim indiE As IIndicatorEntry = cutm.Indicators.Item(kay)

                                    Dim indiMenuItem As New ToolStripMenuItem(indie.ptrIndicator.IndicatorName)
                                    indiMenuItem.Tag = indie

                                    Select Case indie.ptrIndicator.IndicatorType
                                        Case IndicatorType_enum.named
                                            Dim nindicator As NamedIndicatorEntry = indie
                                            indiMenuItem.Text = nindicator.ptrIndicator.IndicatorName & " [" & nindicator.name & "]"
                                            For Each n As String In DirectCast(nindicator.ptrIndicator, NamedIndicator).names

                                                '// create a new menuitem
                                                Dim nameMenu As New ToolStripMenuItem(n, Nothing, AddressOf NameChangeMenuPressed)
                                                nameMenu.Tag = indie
                                                indiMenuItem.DropDownItems.Add(nameMenu)
                                            Next

                                        Case IndicatorType_enum.namedvalue
                                            Dim nvindi As NamedValueIndicatorEntry = indie
                                            indiMenuItem.Text = nvindi.ptrIndicator.IndicatorName & "[" & nvindi.Name & "]"
                                            For Each n As String In DirectCast(nvindi.ptrIndicator, NamedValueIndicator).Items.Keys
                                                '// new menuitem
                                                Dim nameMenu As New ToolStripMenuItem(n, Nothing, AddressOf NameValueChangePressed)
                                                nameMenu.Tag = indie
                                                indiMenuItem.DropDownItems.Add(nameMenu)

                                            Next

                                        Case IndicatorType_enum.value
                                            Dim valueChange As New ToolStripMenuItem("Change Value", Nothing, AddressOf ValueChangeMenuPressed)
                                            Dim vindi As ValueIndicatorEntry = indie
                                            indiMenuItem.Text = vindi.ptrIndicator.IndicatorName & " (" & vindi.Value & ")"
                                            valueChange.Tag = indie

                                            indiMenuItem.DropDownItems.Add(valueChange)

                                    End Select
                                    '// add the item
                                    _IndicatorMenu.DropDownItems.Add(indiMenuItem)

                                Next

                            End If
                        End If
                    Catch ex As Exception

                    End Try

                Case CampaignerItem_cgd.Unit
                    Dim cutm As ChitUnitTypeMember = cnode.Item
                    _IndicatorMenu.DropDownItems.Clear()
                    Try

                        If Not cutm.Indicators Is Nothing Then
                            If Not cutm.Indicators.Count = 0 Then
                                '// this must be in the CHIT TYPE, not the unit type. lame lame lame

                                'MessageBox.Show("this is testing. currently pointing to ptrUnitType or ptrTokenType, not the actual instance of the chit.", "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)

                                For Each indie As IIndicatorEntry In cutm.Indicators
                                    'Dim indi As IIindciator = cutm.ptrUnitType.Indicators.Item(kay)
                                    'Dim indiE As IIndicatorEntry = cutm.Indicators.Item(kay)

                                    Dim indiMenuItem As New ToolStripMenuItem(indie.ptrIndicator.IndicatorName)
                                    indiMenuItem.Tag = indie

                                    Select Case indie.ptrIndicator.IndicatorType
                                        Case IndicatorType_enum.named
                                            Dim nindicator As NamedIndicatorEntry = indie
                                            indiMenuItem.Text = nindicator.ptrIndicator.IndicatorName & " [" & nindicator.name & "]"
                                            For Each n As String In DirectCast(nindicator.ptrIndicator, NamedIndicator).names

                                                '// create a new menuitem
                                                Dim nameMenu As New ToolStripMenuItem(n, Nothing, AddressOf NameChangeMenuPressed)
                                                nameMenu.Tag = indie
                                                indiMenuItem.DropDownItems.Add(nameMenu)
                                            Next

                                        Case IndicatorType_enum.namedvalue
                                            Dim nvindi As NamedValueIndicatorEntry = indie
                                            indiMenuItem.Text = nvindi.ptrIndicator.IndicatorName & "[" & nvindi.Name & "]"
                                            For Each n As String In DirectCast(nvindi.ptrIndicator, NamedValueIndicator).Items.Keys
                                                '// new menuitem
                                                Dim nameMenu As New ToolStripMenuItem(n, Nothing, AddressOf NameValueChangePressed)
                                                nameMenu.Tag = indie
                                                indiMenuItem.DropDownItems.Add(nameMenu)

                                            Next

                                        Case IndicatorType_enum.value
                                            Dim valueChange As New ToolStripMenuItem("Change Value", Nothing, AddressOf ValueChangeMenuPressed)
                                            Dim vindi As ValueIndicatorEntry = indie
                                            indiMenuItem.Text = vindi.ptrIndicator.IndicatorName & " (" & vindi.Value & ")"
                                            valueChange.Tag = indie

                                            indiMenuItem.DropDownItems.Add(valueChange)

                                    End Select
                                    '// add the item
                                    _IndicatorMenu.DropDownItems.Add(indiMenuItem)

                                Next
                            End If
                        End If
                    Catch ex As Exception
                        HandleException(c_Module, ex)
                    End Try
            End Select

            If _IndicatorMenu.DropDownItems.Count > 0 Then
                _IndicatorMenu.Visible = True
            Else
                _IndicatorMenu.Visible = False
            End If

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub UpdateToolTipText(ByRef cnode As CampaignerItemTreeNode)
        Try
            Select Case cnode.ItemType
                Case CampaignerItem_cgd.Unit
                    Dim mem As ChitMember = cnode.Item
                    cnode.ToolTipText = ""
                    For Each iine As IIndicatorEntry In mem.Indicators
                        cnode.ToolTipText &= iine.displayText & ControlChars.CrLf
                    Next

            End Select


        Catch ex As Exception

        End Try
    End Sub


    Private Sub NameValueChangePressed(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            Dim tsi As ToolStripMenuItem = sender
            Dim nvindi As NamedValueIndicatorEntry = tsi.Tag
            nvindi.Name = tsi.Text

            UpdateToolTipText(Me.tvwBattlegroupView.SelectedNode)

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub ValueChangeMenuPressed(ByVal sender As Object, ByVal e As System.EventArgs)
        Try
            Dim vindi As ValueIndicatorEntry = DirectCast(sender, ToolStripMenuItem).Tag
            Dim min, max, cur As Integer
            min = DirectCast(vindi.ptrIndicator, ValueIndicator).Minimum
            max = DirectCast(vindi.ptrIndicator, ValueIndicator).Maximum
            cur = vindi.Value

            Dim val As Integer
            Try
                val = InputBox("Enter the new value, between " & min & " and " & max & ". Current Value: " & cur, "Enter Value", cur)
                vindi.Value = val
                UpdateToolTipText(Me.tvwBattlegroupView.SelectedNode)

            Catch ex As Exception
                MessageBox.Show("You must enter a numeric value", "Invalid Value", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            End Try

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

    Private Sub NameChangeMenuPressed(ByVal sender As Object, ByVal e As EventArgs)
        Try
            '// passes in the name of new value, as well as the indicator?
            Dim tsi As ToolStripMenuItem = sender

            Dim nindi As NamedIndicatorEntry = tsi.Tag
            nindi.name = tsi.Text
            UpdateToolTipText(Me.tvwBattlegroupView.SelectedNode)

        Catch ex As Exception
            HandleException(c_Module, ex)
        End Try
    End Sub

End Class
